<template>
  <el-dialog
    v-model="addMaterialVisible"
    draggable
    :title="t('set.addMatertial')"
    width="600px"
    @close="closeDia"
  >
    <div v-loading="uploadLoading" class="add-material-dialog">
      <el-form
        ref="materialForm"
        :model="form"
        label-width="120px"
        :rules="rules"
        class="add-material-dialog__form"
      >
        <el-form-item :label="t('set.groupName')" prop="groupId">
          <el-select
            v-model="form.groupId"
            filterable
            clearable
            :placeholder="t('common.selectPlaceholder')"
          >
            <el-option
              v-for="item in materialGroupList"
              :key="'group_' + (item as any).id"
              :label="(item as any).name"
              :value="(item as any).id"
            />
          </el-select>
        </el-form-item>
        
        <!-- 文本 -->
        <template
          v-if="materialType === MaterialType.TEXT || materialType === MaterialType.NICKNAME"
        >
          <el-form-item :label="t('common.text')" prop="fileList">
            <div class="add-material-dialog__upload">
              <el-upload
                ref="importTextM"
                class="upload-demo"
                :before-upload="beforeUploadText"
                action=""
                accept=".txt"
                :file-list="fileList"
                :multiple="false"
                :limit="1"
              >
                <el-button type="primary">{{ t("common.upload") }}</el-button>
                <template #tip>
                  <div class="el-upload__tip">{{ t("sup.materialT1") }}</div>
                </template>
              </el-upload>
            </div>
          </el-form-item>
          <el-form-item v-show="uploadWaitingTitle" label="">
            <span class="text-blue-500">{{ uploadWaitingTitle }}</span>
          </el-form-item>
        </template>
        
        <!-- 图文链接 -->
        <template v-else-if="materialType === MaterialType.LINK">
          <el-form-item :label="t('common.title')" prop="linkTitle">
            <el-input v-model="form.linkTitle" :placeholder="t('sup.enterTitle')" />
          </el-form-item>
          <el-form-item :label="t('common.content')" prop="linkText">
            <el-input
              v-model="form.linkText"
              type="textarea"
              :rows="4"
              :placeholder="t('sup.enterContent')"
            />
          </el-form-item>
          <el-form-item :label="t('common.link')" prop="sourceUrl">
            <el-input v-model="form.sourceUrl" :placeholder="t('sup.enterContent')" />
          </el-form-item>
          <el-form-item :label="t('sup.attachedText')">
            <el-input
              v-model="form.attachedText"
              type="textarea"
              :rows="4"
              :placeholder="t('sup.enterContent')"
            />
          </el-form-item>
          <el-form-item :label="t('common.image')">
            <div class="add-material-dialog__upload">
              <el-upload
                ref="importLinkPM"
                class="upload-demo"
                :before-upload="beforeUploadMedia"
                action=""
                :file-list="fileList"
                :limit="1"
              >
                <el-button type="primary">{{ t("common.upload") }}</el-button>
              </el-upload>
            </div>
          </el-form-item>
        </template>
        
        <!-- 名片 -->
        <template v-else-if="materialType === MaterialType.CARD">
          <el-form-item :label="t('session.cardName')" prop="firstName">
            <el-input v-model="form.firstName" :placeholder="t('session.enterContent')" />
          </el-form-item>
          <el-form-item :label="t('session.cardDisplayName')" prop="displayName">
            <el-input v-model="form.displayName" :placeholder="t('session.enterContent')" />
          </el-form-item>
          <el-form-item :label="t('session.cardPhone')" prop="telNumber">
            <el-input v-model="form.telNumber" :placeholder="t('session.addPhoneNotice')" />
          </el-form-item>
        </template>
        
        <!-- 投票 -->
        <template v-else-if="materialType === MaterialType.POLL">
          <el-form-item :label="t('poll.topic')" prop="pollTopic">
            <el-input v-model="form.pollTopic" :placeholder="t('poll.enterTopic')" />
          </el-form-item>
          <el-form-item :label="t('poll.options')" prop="pollOptions">
            <div class="add-material-dialog__poll-options">
              <div v-for="(option, index) in form.pollOptions" :key="index" class="poll-option">
                <el-input
                  v-model="form.pollOptions[index]"
                  :placeholder="t('poll.enterOption')"
                >
                  <template v-if="form.pollOptions.length > 2" #append>
                    <el-button :icon="Minus" @click="removePollOption(index)" />
                  </template>
                </el-input>
              </div>
              <div>
                <el-button type="primary" :icon="Plus" @click="addPollOption">
                  {{ t("poll.addOption") }}
                </el-button>
                <div class="poll-tip">
                  {{ t("poll.atLeastTwoOptions") }}
                </div>
              </div>
            </div>
          </el-form-item>
          <el-form-item :label="t('poll.allowNumber')" prop="allowNumber">
            <el-input-number v-model="form.allowNumber" :min="1" :max="form.pollOptions.length" />
          </el-form-item>
        </template>
        
        <!-- 媒体上传 -->
        <template v-else>
          <el-form-item :label="t('material.mediaFile')" prop="fileList">
            <div class="add-material-dialog__upload">
              <el-upload
                ref="importImgM"
                class="upload-demo"
                :before-upload="beforeUploadMedia"
                action=""
                :file-list="fileList"
                :accept="uploadAccept"
                multiple
                :limit="100"
              >
                <el-button type="primary">{{ t("common.upload") }}</el-button>
                <template #tip>
                  <div class="el-upload__tip">一次最多可上传100个，单个大小不超过5M</div>
                </template>
              </el-upload>
            </div>
          </el-form-item>
          <el-form-item v-show="fileList.length" label="">
            <span>
              <span class="text-blue-500 text-lg">{{ fileList.length }}</span>
              {{ t("sup.materialT3") }}
              <span class="text-red-500 text-lg">{{ resourceList.length }}</span>
              {{ uploadWaitingTitle }}
            </span>
          </el-form-item>
        </template>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" :disabled="disabled" @click="onSubmit">
          {{ t("common.sureBtn") }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, computed, type PropType } from 'vue'
import {
  ElDialog,
  ElForm,
  ElFormItem,
  ElSelect,
  ElOption,
  ElUpload,
  ElButton,
  ElInput,
  ElInputNumber,
  ElMessage
} from 'element-plus'
import { Plus, Minus } from '@element-plus/icons-vue'
import {
  MaterialType,
  MaterialTypeToMapping,
  type MaterialTypeKeys,
  type CardInfo,
  type LinkInfo
} from './types/index'
import type { MaterialAPI } from './api/index'
import { getMaterialUploadAccept } from './utils/index'

// 定义 props
const props = defineProps({
  addMaterialVisible: {
    type: Boolean,
    default: false,
  },
  materialType: {
    type: String,
    required: true,
  },
  materialGroupList: {
    type: Array,
    default: () => [],
  },
  useType: {
    type: Number,
    default: 1,
  },
  materialAPI: {
    type: Object as PropType<MaterialAPI>,
    required: true,
  },
  uploadHandler: {
    type: Function,
    default: null,
  },
  t: {
    type: Function,
    default: (key: string) => key,
  },
})

// 定义 emits
const emit = defineEmits<{
  (e: 'update:addMaterialVisible', value: boolean): void
  (e: 'materialAdded'): void
}>()

interface MaterialForm {
  groupId: string
  firstName: string
  displayName?: string
  telNumber: string
  linkTitle: string
  linkText: string
  sourceUrl: string
  attachedText: string
  pollTopic: string
  pollOptions: string[]
  allowNumber: number
}

// 响应式数据
const form = ref<MaterialForm>({
  groupId: '',
  firstName: '',
  displayName: '',
  telNumber: '',
  linkTitle: '',
  linkText: '',
  sourceUrl: '',
  attachedText: '',
  pollTopic: '',
  pollOptions: ['', ''], // 默认有两个选项
  allowNumber: 1,
})

const fileList = ref<any>([])
const resourceList = ref<any>([])
const uploadLoading = ref(false)
const uploadWaitingTitle = ref('')
const disabled = ref(false)
const materialForm = ref()

const rules = reactive({
  groupId: [{ required: true, message: '请选择素材分组', trigger: 'change' }],
  linkTitle: [{ required: true, message: '请输入标题', trigger: 'change' }],
  linkText: [{ required: true, message: '请输入内容', trigger: 'change' }],
  sourceUrl: [{ required: true, message: '请输入链接', trigger: 'change' }],
  firstName: [{ required: true, message: '请输入姓名', trigger: 'change' }],
  displayName: [{ required: true, message: '请输入显示名称', trigger: 'change' }],
  telNumber: [{ required: true, message: '请输入电话', trigger: 'change' }],
  pollTopic: [{ required: true, message: '请输入投票主题', trigger: 'change' }],
})

// 默认翻译函数
const t = props.t

// 计算上传文件类型
const uploadAccept = computed(() => {
  return getMaterialUploadAccept(props.materialType as MaterialTypeKeys, t as (key: string) => string)
})

// 对话框显示状态
const addMaterialVisible = ref(false)

// 监听 props 中 addMaterialVisible 的变化
watch(
  () => props.addMaterialVisible,
  (newValue) => {
    addMaterialVisible.value = newValue
    if (newValue) {
      resetForm()
    }
  }
)

// 监听 addMaterialVisible 变化并通知父组件
watch(addMaterialVisible, (newValue) => {
  emit('update:addMaterialVisible', newValue)
})

// 方法定义
const resetForm = () => {
  uploadWaitingTitle.value = ''
  form.value.groupId = ''
  resourceList.value = []
  fileList.value = []
  form.value = {
    groupId: '',
    firstName: '',
    displayName: '',
    telNumber: '',
    linkTitle: '',
    linkText: '',
    sourceUrl: '',
    attachedText: '',
    pollTopic: '',
    pollOptions: ['', ''],
    allowNumber: 1,
  }
}

const closeDia = () => {
  addMaterialVisible.value = false
  emit('update:addMaterialVisible', false)
}

// 添加投票选项
const addPollOption = () => {
  form.value.pollOptions.push('')
}

// 删除投票选项
const removePollOption = (index: number) => {
  form.value.pollOptions.splice(index, 1)
}

// 文本上传解析txt内容
const beforeUploadText = (file: File) => {
  const reader = new FileReader()
  reader.onload = (e: any) => {
    if (e.target.result) {
      const lines = e.target.result.split('\n').filter((line: string) => line.trim())
      resourceList.value = lines
      uploadWaitingTitle.value = file.name
    }
  }
  reader.readAsText(file, 'utf-8')
  return false
}

// 媒体上传
const beforeUploadMedia = async (file: any) => {
  // 单个文件不能超过5M
  if (file.size > 5 * 1024 * 1024) {
    ElMessage.error(t('material.file_size_limit_error', { fileName: file.name }))
    return false
  }
  
  fileList.value.push(file)
  
  // 如果有自定义上传处理函数，使用它
  if (props.uploadHandler) {
    try {
      const uploadInfo = await props.uploadHandler(file, true)
      const { key } = uploadInfo
      resourceList.value.push({
        name: file.name,
        url: key,
      })
    } catch (error) {
      console.error('文件上传失败:', error)
      ElMessage.error('文件上传失败')
    }
  } else {
    // 默认处理：直接使用文件名作为URL（用于测试）
    resourceList.value.push({
      name: file.name,
      url: file.name,
    })
  }
  
  return false
}

// 添加素材
const onSubmit = async () => {
  if (form.value.groupId === '') {
    ElMessage.error(t('material.selectMaterialGroup'))
    return
  }

  try {
    disabled.value = true
    
    // 文本和昵称
    if (props.materialType === MaterialType.TEXT || props.materialType === MaterialType.NICKNAME) {
      if (resourceList.value.length === 0) {
        ElMessage.error(t('material.uploadMaterialFile'))
        return
      }
      
      for (const text of resourceList.value) {
        await props.materialAPI.createMaterial({
          type: MaterialTypeToMapping(props.materialType as MaterialTypeKeys),
          groupId: form.value.groupId,
          name: props.materialType,
          content: text,
          useType: props.useType,
        })
      }
    } else if (props.materialType === MaterialType.CARD) {
      // 名片
      if (!form.value.firstName || !form.value.displayName || !form.value.telNumber) {
        ElMessage.error('请填写名片信息')
        return
      }
      
      const cardInfo: CardInfo = {
        firstName: form.value.firstName,
        displayName: form.value.displayName,
        telNumber: form.value.telNumber,
      }
      
      await props.materialAPI.createMaterial({
        type: MaterialTypeToMapping(props.materialType as MaterialTypeKeys),
        groupId: form.value.groupId,
        name: props.materialType,
        content: JSON.stringify(cardInfo),
        useType: props.useType,
      })
    } else if (props.materialType === MaterialType.LINK) {
      // 链接
      if (!form.value.sourceUrl || !form.value.linkText) {
        ElMessage.error('请填写链接和文本')
        return
      }

      const data: LinkInfo = {
        text: form.value.sourceUrl,
        title: form.value.linkTitle,
        description: form.value.linkText,
        matchedText: form.value.attachedText ? form.value.attachedText.replace(/[\r\n]+/g, '') : '',
        jpegThumbnail: '',
      }
      
      if (resourceList.value && resourceList.value.length > 0) {
        data.jpegThumbnail = resourceList.value[0].url
      }
      
      await props.materialAPI.createMaterial({
        type: MaterialTypeToMapping(props.materialType as MaterialTypeKeys),
        groupId: form.value.groupId,
        name: props.materialType,
        content: JSON.stringify(data),
        useType: props.useType,
      })
    } else if (props.materialType === MaterialType.POLL) {
      // 投票
      if (!form.value.pollTopic || form.value.pollOptions.length < 2) {
        ElMessage.error('请填写投票主题和至少两个选项')
        return
      }
      
      const data = {
        question: form.value.pollTopic,
        options: form.value.pollOptions.filter((option) => option.trim() !== ''),
        selectableOptionCount: form.value.allowNumber,
      }
      
      await props.materialAPI.createMaterial({
        type: MaterialTypeToMapping(props.materialType as MaterialTypeKeys),
        groupId: form.value.groupId,
        name: props.materialType,
        content: JSON.stringify(data),
        useType: props.useType,
      })
    } else {
      // 媒体素材类
      if (resourceList.value.length === 0) {
        ElMessage.error(t('material.uploadMaterialFile'))
        return
      }
      
      for (const item of resourceList.value) {
        await props.materialAPI.createMaterial({
          type: MaterialTypeToMapping(props.materialType as MaterialTypeKeys),
          groupId: form.value.groupId,
          name: item.name,
          content: item.url,
          useType: props.useType,
        })
      }
    }
    
    ElMessage.success(t('material.addSuccessAndRefresh'))
    emit('materialAdded')
    closeDia()
  } catch (error) {
    console.error('添加素材失败:', error)
    ElMessage.error(t('common.handleError'))
  } finally {
    disabled.value = false
  }
}
</script>

<style lang="scss" scoped>
.add-material-dialog {
  &__form {
    .el-form-item {
      margin-bottom: 20px;
    }
  }

  &__upload {
    .el-upload__tip {
      color: var(--el-text-color-secondary);
      font-size: 12px;
      margin-top: 8px;
    }
  }

  &__poll-options {
    .poll-option {
      margin-bottom: 8px;
    }

    .poll-tip {
      color: var(--el-text-color-secondary);
      font-size: 12px;
      margin-top: 4px;
    }
  }
}

.text-blue-500 {
  color: #3b82f6;
}

.text-red-500 {
  color: #ef4444;
}

.text-lg {
  font-size: 18px;
}
</style>